package 
{
  import assets.dialog;
  import assets.ococ;
  import assets.ui;
  import com.bit101.components.FPSMeter;
  import flash.display.Bitmap;
  import flash.display.DisplayObjectContainer;
  import flash.display.MovieClip;
  import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
  import flash.geom.Matrix;
  import flash.geom.Point;
  import mge.particles.Descriptor;
  import mge.particles.ParticleSystem;
  import mge.serialization.Serializer;
  import mge.ui.Input;
  import mge.Timer;
  import mge.ui.TextTyped;

	/**
	 * ...
	 * @author Ivan
	 */
	[Frame(factoryClass="Preloader")]
	public class Main extends Sprite 
	{
    public static const WIDTH:int = 480;
    public static const HEIGHT:int = 800;
    
    private const GUY_Y:Number = 500;
    
    private const GRAVITY:Number = 1600;
    private const JUMP_STRENGHT:Number =  800;
    private const JET_POWER:Number = 2000;
    
    //[Embed(source = '../assets/ococ.png')]
    //private var ococ:Class;
    
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
      
      drawBackground();
      
      
      addEventListener(Event.ENTER_FRAME, onEnterFrame);
      
      Input.RegisterListeners(stage);
      
      gameContainer = new Sprite();
      addChild(gameContainer);
      
      
      /////////// TEST
      if (0)
      {
        platformsContainer = new Sprite();
        var n:int = Platform.BLUR_LEVELS;
        for (var i:int = 0; i < n; i++)
        {
          var p:Platform = new Platform();
          p.x = (i/n) * WIDTH;
          p.y = (i / n)*HEIGHT;
          platformsContainer.addChild(p);
          p.draw(i);
          platforms.push(p);
        }      
        gameContainer.addChild(platformsContainer);
        removeEventListener(Event.ENTER_FRAME, onEnterFrame);
        return;
      }
      /////////// TEST
      
      // Adds platforms
      platformsContainer = new Sprite();      
      var n:int = 50;
      for (var i:int = 0; i < n; i++)
      {
        var p:Platform = new Platform();
        p.x = Math.random() * (WIDTH - Platform.WIDTH);
        p.y = -5000 + (i / n) * (5000 + HEIGHT + Math.random() * 100 - 50);
        platformsContainer.addChild(p);
        platforms.push(p);
      }      
      gameContainer.addChild(platformsContainer);
      verticalSpeed = JUMP_STRENGHT;
      updateTimer.start();
      
      // Adds the robot-guy.
      guy = new assets.ococ();
      guy.x = WIDTH / 2;
      guy.y = GUY_Y;
      gameContainer.addChild(guy);
      
      guyController = new GuyController(guy);      
      
      platformsContainer.addChild(particles.jet);
            
      ui = new assets.ui();
      addChild(ui);
      
      dialog = new assets.dialog();
      var typed:TextTyped = new TextTyped(dialog.text);
      typed.type("<p>Please HELP!! </p><p>I need to find my ship! </p>");
      addChild(dialog);
      
      new FPSMeter(this);
		}
    
    private var jetEnabled:Boolean;
    private function onEnterFrame(e:Event):void
    {
      if (playing)
      {
        if (Input.isDown(Input.KEY_UP) && energy > 0)
        {
          particles.jet.fire();
          jetEnabled = true;
        }
        if (Input.isUp(Input.KEY_UP))
        {
          particles.jet.stop();
          jetEnabled = false;
        }
        updateMovement();
        updateEnergy();
        score = Math.max(score, -guy.y + GUY_Y);
        ui.score.text = "SCORE: " + ((int)(score)).toString();
        guyController.update();
      }
      else
      {
        if (Input.isUp(Input.MOUSE_LBUTTON))
        {
          playing = true;
          removeChild(dialog);
        }
      }
      
      particles.update();      
      particles.jet.descriptor.position.x = guy.x;
      particles.jet.descriptor.position.y = guy.y;
      
      drawPlatforms();
      
      Input.update();
    }
    
    private function drawPlatforms():void
    {
      var blur:int = Math.min(Platform.BLUR_LEVELS - 1, (int)((Math.abs(verticalSpeed) / GRAVITY) * Platform.BLUR_LEVELS));
      for (var i:int = 0; i < platforms.length; i++)
        platforms[i].draw(blur);
    }
    
    private function updateMovement():void
    {
      var delta:Number = updateTimer.getDelta();
      updateTimer.start();
      
      var old_y:Number = guy.y;
      guy.y -= verticalSpeed * delta;
      gameContainer.y = -guy.y + GUY_Y;
      // gameContainer.z = Math.max(0, verticalSpeed * 0.2);
      verticalSpeed -= GRAVITY * delta;
      
      // Handle jet
      if (jetEnabled) verticalSpeed += JET_POWER * delta;      
    
      if (verticalSpeed < 0 && guy.currentLabel == "normal")
      {
        var colPlatforms:Vector.<Platform> = platforms.filter(collide_x, this);
        colPlatforms = colPlatforms.filter(collide_y, this);
        if (colPlatforms.length > 0)
        {
          guy.gotoAndPlay("jump");
          verticalSpeed = JUMP_STRENGHT;
          particles.startSmoke(platformsContainer, new Point(guy.x, guy.y));
        }
      
        function collide_x(item:Platform, index:int, vector:Vector.<Platform>):Boolean {
          if (guy.x < item.x) return false;
          if (guy.x > item.x + item.width) return false;
          return true;
        }
        
        function collide_y(item:Platform, index:int, vector:Vector.<Platform>):Boolean {
          if (old_y < item.y && guy.y > item.y) return true;
          return false;
        }
      }
            
    }
    
    private function updateEnergy():void
    {
      if (guy.currentLabel == "stunt_1")
      {
        energy += 0.1;
        if (energy > 100) energy == 100;
        ui["energy_bar"].gotoAndStop((int)(energy));
      }
      
      if (jetEnabled)
      {
        energy -= 0.5;
        if (energy < 0)
        {
          energy == 0
          jetEnabled = false;
          particles.jet.stop();
        }
        ui["energy_bar"].gotoAndStop((int)(energy));
      }
    }
    
    
    private function drawBackground():void
    {
      graphics.clear();
      graphics.beginFill(0xc4dfe0ff);
      
      for (var i:int = 0; i < 250; i++)
      {
        graphics.drawCircle(Math.random() * WIDTH, Math.random() * HEIGHT,  1 + Math.random() * 1);
      }
      
      graphics.endFill();
    }
    
    private var updateTimer:Timer = new Timer(1000);
    private var verticalSpeed:Number;
    
    private var gameContainer:Sprite; // For z effects.
    private var platformsContainer:Sprite; // For blur effects.
    private var platforms:Vector.<Platform> = new Vector.<Platform>();
    private var guyController:GuyController;
    private var ui:assets.ui;
    private var guy:MovieClip;
    private var score:Number = 0;
    private var energy:Number = 0;
    
    private var particles:Particles = new Particles();
    
    private var playing:Boolean;

    private var dialog:assets.dialog;
	}

}